home *** CD-ROM | disk | FTP | other *** search
- /*
- * RemoteExecute
- *
- * Führt eine Befehlszeile in einer Shell auf dem angegebenen Rechner aus.
- * Außerdem kann die Ausgabedatei angegeben werden.
- *
- * Template: HOSTNAME/A,COMMAND/A,OUTPUT/K
- * Beispiel: RemoteExecute Amiga1 "dir c:" "ram:ausgabe"
- *
- * Diese Version benutzt den GPServer.
- */
-
- #define VERSION "1.0"
- #define DATE "12.9.94"
- #define PROGNAME "RemoteExecute"
-
- /*
- * Include-Dateien
- */
- #include <stdlib.h>
- #define USE_BUILTIN_MATH
- #include <string.h>
-
- #include <envoy/envoy.h>
- #include <envoy/errors.h>
- #include <exec/memory.h>
-
- #include <clib/dos_protos.h>
- #include <pragmas/dos_pragmas.h>
- #include <clib/exec_protos.h>
- #include <pragmas/exec_sysbase_pragmas.h>
- #include <clib/nipc_protos.h>
- #include <pragmas/nipc_pragmas.h>
-
- #include "GPServer.h"
-
- /*
- * globale Datan
- */
-
- /* libraries */
- extern struct Library *DOSBase;
- extern struct Library *SysBase;
- static struct Library *NIPCBase;
-
- /* version string */
- static const char version[] = "\0$VER: " PROGNAME " " VERSION " (" DATE ")";
-
- /* Daten & Definitionen für die Parameter */
- #define TEMPLATE "HOSTNAME/A,COMMAND/A,OUTPUT/K"
- #define OPTN_HOSTNAME 0
- #define OPTN_COMMAND 1
- #define OPTN_OUTPUT 2
- #define OPTN_COUNT 3
- static long options[OPTN_COUNT];
- #define HOSTNAME ((unsigned char *)options[OPTN_HOSTNAME])
- #define COMMAND ((unsigned char *)options[OPTN_COMMAND])
- #define OUTPUT ((unsigned char *)options[OPTN_OUTPUT])
-
- /*
- * Prototypen für Funktionen in dieser Datei
- */
- static ULONG remoteexecute(void);
- static BOOL makedatapacket(struct Transaction *ta);
-
- void main()
- {
- struct RDArgs *args;
- ULONG rc = RETURN_OK;
-
- if (SysBase->lib_Version < 37) exit(RETURN_ERROR); /* unter Kick 2.04 geht nichts! */
-
- if (NIPCBase = OpenLibrary("nipc.library", 39))
- {
- /* Parameter auswerten */
- if (args = ReadArgs(TEMPLATE, options, NULL))
- {
- rc = remoteexecute();
- FreeArgs(args);
- }
- else
- {
- /* Fehler bei den Parametern! */
- PrintFault(IoErr(), NULL);
- rc = RETURN_WARN;
- }
-
- CloseLibrary(NIPCBase);
- }
- else PutStr("Kann nipc.library V39 oder neuer nicht öffnen!\n");
-
- exit(rc);
- }
-
- static ULONG remoteexecute(void)
- {
- struct Entity *ausgangs_entity;
- struct Entity *ziel_entity;
- struct Transaction *ta;
- struct Transaction *rta;
- ULONG entitysigbit;
- ULONG error = ENVOYERR_NOERROR;
- ULONG rc = RETURN_ERROR;
- ULONG sigs;
- BOOL quit = FALSE;
-
- /* Private Entity anlegen. Dabei lassen wir für die Entity gleich ein
- * SignalBit belegen. Dieses wird in entitysignal abgelegt.
- */
- if (ausgangs_entity = CreateEntity(ENT_AllocSignal, (ULONG)&entitysigbit, TAG_END))
- {
- /* Kommunikationspfad errichten */
- if (ziel_entity = FindEntity(HOSTNAME, "GPServer", ausgangs_entity, &error))
- {
- /* Nun allozieren wir die Transaction */
- if (ta = AllocTransaction(TAG_END))
- {
- /* Das Datenpaket für die Anfrage schnüren ... */
- if (makedatapacket(ta))
- {
- /* Die Transaction losschicken ... */
- ta->trans_Command = TACMD_CMDLINE;
- BeginTransaction(ziel_entity, ausgangs_entity, ta);
-
- /* Nun warten wir auf die Antwort ... */
- while (!quit)
- {
- sigs = Wait((1 << entitysigbit) | SIGBREAKF_CTRL_C);
-
- if (sigs & (1 << entitysigbit))
- {
- /* Bei unserer Entity ist was angekommen ... */
- while (rta = GetTransaction(ausgangs_entity))
- {
- if (rta->trans_Type == TYPE_RESPONSE)
- {
- /* Unsere Transaction ist zurück ... */
- quit = TRUE;
- }
- else
- {
- /* Das ist nicht unsere Transaction,
- * die wir losgeschickt haben; zur
- * Sicherheit schicken wie sie zurück
- * Dieser Fall darf eigentlich nie auf-
- * treten.
- */
- ReplyTransaction(rta);
- }
- }
- }
-
- if (sigs & SIGBREAKF_CTRL_C)
- {
- /* Bei CTRL-C sollen wir abbrechen:
- * dazu müsen wir die Transaction erst abbrechen.
- */
- AbortTransaction(ta);
- WaitTransaction(ta);
- quit = TRUE;
- }
- }
-
- /* Ist ein Fehler aufgetreten? */
- if (ta->trans_Error == ENVOYERR_NOERROR)
- {
- rc = RETURN_OK;
- }
- else
- {
- Printf("Envoy-Fehler %lu!\n", ta->trans_Error);
- }
-
- /* Datenbereich wieder freigeben */
- FreeMem(ta->trans_RequestData, ta->trans_ReqDataLength);
- }
- /* Transaction freigeben */
- FreeTransaction(ta);
- }
- /* Kommunikationspfad freigeben */
- LoseEntity(ziel_entity);
- }
- else
- {
- Printf("GPServer auf Rechner '%s' nicht erreichbar:\n", HOSTNAME);
- Printf("Envoy-Fehler %lu\n", error);
- }
-
- DeleteEntity(ausgangs_entity);
- }
- else PutStr("Kann Entity nicht erzeugen!\n");
-
- return(rc);
- }
-
- static BOOL makedatapacket(struct Transaction *ta)
- {
- /* Diese Funktion erstellt aus den Kommandozeilenparametern,
- * die uns der Benutzer angegeben hat, ein Datenpaket, wie es
- * der Server versteht.
- */
- ULONG datalen;
- unsigned char *data;
-
- /* Wieviel Bytes an Daten wollen wir an den Server schicken? */
- datalen = strlen(COMMAND) + 2;
- if (OUTPUT) datalen = datalen + strlen(OUTPUT);
-
- if (data = AllocMem(datalen, MEMF_ANY))
- {
- ta->trans_RequestData = data;
- ta->trans_ReqDataLength = datalen;
- ta->trans_ReqDataActual = datalen;
-
- /* Nun müssen wir die Daten noch in der richtigen Form in den
- * allozierten Speicher kopieren:
- * Der GPServer erwartet zuerst den COMMAND-String,
- * dann den OUTPUT-String; beide Strings sind Null-terminiert;
- */
- strcpy(data, COMMAND); /* Kommando kopieren */
- data += strlen(data) + 1; /* Zeiger vor */
- if (OUTPUT) strcpy(data, OUTPUT); /* Output kopieren oder */
- else *data = '\0'; /* noch ein Nullbyte */
-
- return(TRUE);
- }
- return(FALSE);
- }
-